﻿using Microsoft.Win32;
using Org.BouncyCastle.Crypto.Prng;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using static System.Net.Mime.MediaTypeNames;

namespace Common
{
    /// <summary>
    /// 应用程序帮助类
    /// </summary>
    public static class ApplicationTools
    {
        /// <summary>
        /// 单例启动
        /// </summary>
        /// <param name="mutexName">
        /// 在运行终端服务的服务器上，命名系统 mutex 可以有两个级别的可见性。
        /// 如果其名称以前缀 "Global" 开头，则 mutex 在所有终端服务器会话中可见。
        /// 如果其名称以前缀 "Local" 开头，则 mutex 仅在创建它的终端服务器会话中可见。 在这种情况下，可以在服务器上的其他每个终端服务器会话中存在具有相同名称的单独 mutex。
        /// 如果在创建已命名的 mutex 时未指定前缀，则采用前缀 "Local"。 在终端服务器会话中，两个互斥体的名称只是它们的前缀不同，它们都是对终端服务器会话中的所有进程都可见。
        /// 也就是说，前缀名称 "Global" 和 "Local" 描述互斥体名称相对于终端服务器会话的作用域，而不是相对于进程。
        /// </param>
        /// <returns></returns>
        public static System.Threading.EventWaitHandle StartOnece(string mutexName, bool isCrossPlatformApplication = false)
        {
            System.Threading.EventWaitHandle ProgramStarted = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.AutoReset, mutexName, out var createNew);
            if (isCrossPlatformApplication)
            {
                if (!createNew)
                {
                    try
                    {
                        var processes = System.Diagnostics.Process.GetProcessesByName(WorkPath.AssemblyName);
                        if (!processes.Any())
                        {
                            //MessageBox.Show("程序已启动。", "提示提示", MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                        else
                        {
                            foreach (System.Diagnostics.Process process in processes)
                            {
                                Win32API.ShowWindowAsync(process.MainWindowHandle, Win32API.SW_SHOWNOMAL);
                                Win32API.SetForegroundWindow(process.MainWindowHandle);
                                Win32API.SwitchToThisWindow(process.MainWindowHandle, true);
                            }
                        }
                    }
                    catch (Exception exception)
                    {
                        exception.ToString();
                        // Logger.Error(exception, "唤起已启动进程时出错");
                    }

                    //Application.Current.Shutdown();
                    //Environment.Exit(-1);
                    return null;
                }

                return ProgramStarted;
            }
            else
            {
                return createNew ? ProgramStarted : null;
            }
        }

        /// <summary>
        /// 注册Url协议
        /// </summary>
        /// <param name="suffix"></param>
        /// <param name="path"></param>
        /// <param name="friendlyAppName"></param>
        public static void RegistURLProtocol(string suffix, string path, string friendlyAppName = "")
        {
            if (OperatingSystem.IsWindows())
            {
                //window平台
                RegistURLProtocolForWindows(suffix, path, friendlyAppName);
            }
            else if (OperatingSystem.IsLinux())
            {
                //linux平台
                RegistURLProtocolForLinux(suffix, path, friendlyAppName);
            }
            else
            {
                //其他平台
            }
        }

        /// <summary>
        /// 注册Url协议 Windows
        /// </summary>
        /// <param name="suffix"></param>
        /// <param name="path"></param>
        /// <param name="friendlyAppName"></param>
        private static void RegistURLProtocolForWindows(string suffix, string path, string friendlyAppName = "")
        {
            using RegistryKey currentUserSoftwareClassesKey = Registry.CurrentUser.OpenSubKey("Software\\Classes", true);
            {
                if (currentUserSoftwareClassesKey != null)
                {
                    var suffixKey = currentUserSoftwareClassesKey.OpenSubKey(suffix, true);
                    if (suffixKey == null)
                    {
                        suffixKey = currentUserSoftwareClassesKey.CreateSubKey(suffix, true);
                    }
                    suffixKey.SetValue("URL Protocol", "");
                    var suffixShellKey = suffixKey.OpenSubKey("Shell", true);
                    if (suffixShellKey == null)
                    {
                        suffixShellKey = suffixKey.CreateSubKey("Shell", true);
                    }
                    var suffixShellOpenKey = suffixShellKey.OpenSubKey("Open", true);
                    if (suffixShellOpenKey == null)
                    {
                        suffixShellOpenKey = suffixShellKey.CreateSubKey("Open", true);
                    }
                    var suffixShellOpenNames = suffixShellOpenKey.GetValueNames();
                    suffixShellOpenKey.SetValue("FriendlyAppName", friendlyAppName);

                    var suffixShellOpenCommandKey = suffixShellOpenKey.OpenSubKey("Command", true);
                    if (suffixShellOpenCommandKey == null)
                    {
                        suffixShellOpenCommandKey = suffixShellOpenKey.CreateSubKey("Command", true);
                    }
                    suffixShellOpenCommandKey.SetValue("", "\"" + path.Replace("\\", "\\\\") + "\" \"%1\"");
                }
            }
        }



        /// <summary>
        /// 注册Url协议 Linux
        /// </summary>
        /// <param name="suffix"></param>
        /// <param name="path"></param>
        /// <param name="friendlyAppName"></param>
        private static void RegistURLProtocolForLinux(string suffix, string path, string friendlyAppName = "")
        {
            string desktopSharePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            if (!Directory.Exists(desktopSharePath))
            {
                Directory.CreateDirectory(desktopSharePath);
            }
            string desktopFilePath = Path.Combine(desktopSharePath, "applications", suffix + ".desktop");
            string desktopEntry =
                "[Desktop Entry]" + Environment.NewLine +
                "Encoding=UTF-8" + Environment.NewLine +
                "Version=1.0" + Environment.NewLine +
                "Type=Application" + Environment.NewLine +
                "Terminal=false" + Environment.NewLine +
                "Exec=" + path + " %u" + Environment.NewLine +
                "Name=" + friendlyAppName + Environment.NewLine +
                "Comment=" + friendlyAppName + " handler" + Environment.NewLine +
                "Categories=Application;Network;" + Environment.NewLine +
                "MimeType=x-scheme-handler/" + suffix + ";" + Environment.NewLine;

            File.WriteAllText(desktopFilePath, desktopEntry);

            //普通用户配置
            //cp foo.desktop ~/.local/share/applications/;
            //update-desktop-database ~/.local/share/applications/
            //cd ~/.local/share/applications/
            //xdg-mime default foo.desktop x-scheme-handler/foo
            Process.Start("update-desktop-database", desktopSharePath);
            Process.Start("xdg-mime", "default " + desktopFilePath + " x-scheme-handler/" + suffix);
        }
    }
}
